package com.bagus.mediapipefacedetection.module.detect;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.hardware.Camera;
import android.util.Log;


import com.bagus.mediapipefacedetection.camera.CameraFactory;
import com.bagus.mediapipefacedetection.camera.CameraManager;
import com.bagus.mediapipefacedetection.camera.CameraWrapper;
import com.bagus.mediapipefacedetection.constant.ErrorType;
import com.bagus.mediapipefacedetection.constant.ImageMode;
import com.bagus.mediapipefacedetection.listener.ResultEntity;
import com.bagus.mediapipefacedetection.manager.DetectQualityManager;
import com.bagus.mediapipefacedetection.module.base.BasePresenter;
import com.bagus.mediapipefacedetection.quality.DetectQualityInfo;
import com.bagus.mediapipefacedetection.quality.DetectQualityStatus;
import com.bagus.mediapipefacedetection.quality.DetectQualityThreshold;
import com.bagus.mediapipefacedetection.utils.ImageUtil;
import com.bagus.mediapipefacedetection.utils.ModelUtil;
import com.bagus.mediapipefacedetection.utils.NoDoubleClickUtil;

import java.io.File;

public class DetectPresenter extends BasePresenter<DetectContract.View, DetectModel> implements DetectContract.Presenter, CameraWrapper.CameraOpenCallback, CameraWrapper.ICameraCallback {
    private static final String TAG = "DetectPresenter";
    private DetectThread mDetectThread;
    private int mImageBufferAngle;
    private boolean isCameraOpened = false;
    private Object object = new Object();
    private Activity activity;
    private int mCamraId = 0;  //1是前置摄像头   0是后置摄像头

    public DetectPresenter() {
    }

    public DetectPresenter(Activity activity) {
        this.activity = activity;
    }

    public DetectPresenter(Activity activity, int mCamraId, DetectContract.View view) {
        this.activity = activity;
        if (getModel() == null) {
            attach(view);
        }
        setmView(view);
        this.mCamraId = mCamraId;
    }

    @Override
    public void init() {
        super.init();
        initDetect();
    }

    private void initDetect() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (getView() != null) {
                    synchronized (object) {

//                        boolean ret = getModel().init(ModelUtil.readModel(getView().getContext(), R.raw.track)
//                                , ModelUtil.readModel(getView().getContext(), R.raw.mouth)
//                                , ModelUtil.readModel(getView().getContext(), R.raw.eye)
//                                , ModelUtil.readModel(getView().getContext(), R.raw.pose)
//                                , ModelUtil.readModel(getView().getContext(), R.raw.blurness));
//                        if (!ret) {
//                            getView().onExit(ErrorType.MGFacePPSkinAICameraErrorLoadModelFailed, null);
//                        }
                    }
                    getView().initFinish();
                }
            }
        }).start();
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        try {
            mFrameDataQueue.offer(data);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean startPreview() {
        try {
            if (mCameraManager != null && getView().getSurfaceTexture() != null && isCameraOpened) {
                if (mCameraManager.isFrontCam()) {
                    mImageBufferAngle = 90;
                } else {
                    mImageBufferAngle = 270;
                }
                CameraFactory.mImageBufferAngle = mImageBufferAngle;
                mCameraManager.setDisplayOrientation();
                mCameraManager.startPreview(getView().getSurfaceTexture());
                mCameraManager.actionDetect(this);
                getView().cameraOpened();
                return true;
            }
        } catch (Throwable e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    @Override
    public void stopPreview() {
        try {
            if (mCameraManager != null) {
//                ILogPrint.logw(TAG, "stopPreview...");
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    @Override
    public void switchCamera() {
        try {
            if (mCameraManager == null) {
                this.mCameraManager = new CameraManager(getView().getActivity(), mCamraId);
            }
            if (mCameraManager != null) {
                if (!NoDoubleClickUtil.isFastDoubleClick()) {
                    isCameraOpened = false;
                    mCameraManager.switchCamera();
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean openCamera() {
        try {
            if (mCameraManager == null) {
                this.mCameraManager = new CameraManager(getView().getActivity(), mCamraId);
            }
            if (mCameraManager != null) {
                isCameraOpened = false;
                this.mCameraManager.setmCameraOpenCallback(this);
                this.mCameraManager.openCamera();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    public void closeCamera() {
        try {
            if (mCameraManager != null) {
                mCameraManager.closeCamera();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    @Override
    public void startDetect() {
        try {
            mDetectThread = new DetectThread();
            if (mCameraManager == null) {
                this.mCameraManager = new CameraManager(getView().getActivity(), mCamraId);
            }
            if (mCameraManager.isFrontCam()) {
                mImageBufferAngle = 90;
            } else {
                mImageBufferAngle = 270;
            }
            if (mDetectThread != null) {
                getModel().reset();
                getModel().startDetect();
                mDetectThread.setDetecting(true);
                mDetectThread.start();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    @Override
    public void stopDetect() {
        try {
            if (mDetectThread != null) {
                mDetectThread.setDetecting(false);
                getModel().stopDetect();
                mDetectThread.interrupt();
                mDetectThread = null;
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    @Override
    public void detach() {
        try {
            synchronized (object) {
                if (getModel() != null) {
                    getModel().release();
                }
            }
            closeCamera();
            super.detach();
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean isCameraOpenSuccess() {
        return isCameraOpened;
    }

    @Override
    public void onOpenSuccess() {
        isCameraOpened = true;
        startPreview();
    }

    @Override
    public void onDisconnected() {

    }

    @Override
    public void onOpenFailed() {
        if (getView() != null)
            getView().onExit(ErrorType.MGFacePPSkinAICameraErrorNotCameraSupport, null);
    }

    private boolean fflag = false;

    @Override
    public void onCapturePicture(byte[] data) {
        if (data != null) {
            if (!fflag) {
                fflag = true;
                Log.e("biubiu", "onCapturePicture: data != null");
                mDetectThread.setDetecting(false);
                getModel().reset();
//                for (int i = 0; i < 10; i++) {
//                    DetectQualityInfo bean = getModel().detect(ImageMode.FACESTYLE_IMAGEMODE_NV21.ordinal(), data, mCameraManager.getPictureWidth(), mCameraManager.getPictureHeight(), mImageBufferAngle);
//                    if (bean != null) {
//                        Log.e("biubiu", "onCapturePicture: start hadle picture i == " + i);
//                        handlePictureResult(bean, data);
//                        fflag = false;
//                        return;
//                    }
//                }
                stopDetect();
                startDetect();
                fflag = false;
                isPictureToken = false;
            }
        } else {
            Log.e("biubiu", "onCapturePicture: data == null");
            isPictureToken = false;
            getView().onExit(ErrorType.MGFacePPSkinAICameraErrorTakeFailed, null);
        }
    }

    class DetectThread extends Thread {
        private boolean detecting = false;

        public void setDetecting(boolean detecting) {
            this.detecting = detecting;
        }

        public boolean getDetecting() {
            return detecting;
        }

        @Override
        public void run() {
            while (detecting) {
                try {
                    byte[] image = mFrameDataQueue.take();
//                    DetectQualityInfo bean = getModel().detect(ImageMode.FACESTYLE_IMAGEMODE_NV21.ordinal(), image, CameraFactory.mWidth, CameraFactory.mHeight, mImageBufferAngle);
//                    DetectQualityStatus status = getModel().getQualityStatus(bean);
//                    handleDetectResult(status);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
            }
        }
    }

    private boolean isPictureToken = false;

    private void handleDetectResult(DetectQualityStatus status) {
        if (status == DetectQualityStatus.MGFacePPSkinAICameraFaceFinish) {
            //拍照
            if (!isPictureToken) {
                isPictureToken = true;
                Log.e("biubiu", "handleDetectResult: takePicture");
                mCameraManager.takePicture();
            }
        } else {
            isPictureToken = false;
            getView().setUserTips(status.ordinal());
        }
    }

    private void handlePictureResult(DetectQualityInfo info, byte[] data) {
        Bitmap b = null;
        Bitmap orgBitmap = null;
        if (data != null) {
            DetectQualityThreshold threshold = DetectQualityManager.getInstance().getThreshold();
            int width = info.getFaceRect().right - info.getFaceRect().left;
            int height = info.getFaceRect().bottom - info.getFaceRect().top;
            Rect rectFace = new Rect();
            rectFace.top = (int) (info.getFaceRect().top - height * threshold.getFaceImageCutDownOffset() / 2);
            rectFace.bottom = (int) (info.getFaceRect().bottom + height * threshold.getFaceImageCutDownOffset() / 2);
            if (mImageBufferAngle == 90) {
                rectFace.right = (int) (info.getFaceRect().right + width * threshold.getFaceImageCutDownOffset() * 3.2);
                rectFace.left = (int) (rectFace.right - width * (1 + threshold.getFaceImageCutDownOffset() * 3.7));
            } else if (mImageBufferAngle == 270) {
                rectFace.left = (int) (info.getFaceRect().left - width * threshold.getFaceImageCutDownOffset() * 3.2);
                rectFace.right = (int) (rectFace.left + width * (1 + threshold.getFaceImageCutDownOffset() * 3.7));
            }
            rectFace.left = Math.max(rectFace.left, 0);
            rectFace.top = Math.max(rectFace.top, 0);
            rectFace.right = Math.min(rectFace.right, mCameraManager.getPictureWidth());
            rectFace.bottom = Math.min(rectFace.bottom, mCameraManager.getPictureHeight());
            b = ImageUtil.resizeBitmap(data, mCameraManager.getPictureWidth(), mCameraManager.getPictureHeight(), rectFace);
            orgBitmap = ImageUtil.resizeBitmap(data, mCameraManager.getPictureWidth(), mCameraManager.getPictureHeight(), new Rect(0, 0, mCameraManager.getPictureWidth(), mCameraManager.getPictureHeight()));
        }
        if (null != b && null != orgBitmap) {
            Bitmap rotaCutDownBitmap = ImageUtil.getRotateBitmap(b, 360 - mImageBufferAngle);
            Bitmap orgCutDownBitmap = ImageUtil.getRotateBitmap(orgBitmap, 360 - mImageBufferAngle);
//            long l = System.currentTimeMillis();
//            if (getView() != null) {
//                ImageUtil.saveImageToGallery(getView().getContext(), rotaCutDownBitmap, "face_cutdown_" + l + ".jpg");
//            }
//            if (getView() != null) {
//                ImageUtil.saveImageToGallery(getView().getContext(), orgCutDownBitmap, "face_org_" + l + ".jpg");
//            }
//            isPictureToken = true;
//            if (getView() != null) {
//                getView().detectFinish(ErrorType.MGFacePPSkinAICameraErrorNone, new ResultEntity(rotaCutDownBitmap, info.getFaceRect(), data));
//            }
            if (getView() != null) {
                ImageUtil.saveImageToCacheFile(getView().getContext(), rotaCutDownBitmap, "face_cutdown.jpg");
                ImageUtil.saveImageToCacheFile(getView().getContext(), orgCutDownBitmap, "face_org.jpg");
            }
            isPictureToken = true;
            if (getView() != null) {
                getView().detectFinish(ErrorType.MGFacePPSkinAICameraErrorNone, new ResultEntity(
                        getView().getContext().getFilesDir() + File.separator + "skin_picture" + File.separator + "face_org.jpg",
                        getView().getContext().getFilesDir() + File.separator + "skin_picture" + File.separator + "face_cutdown.jpg"));
            }
        }
    }
}
